<template>
    <div class="container" :info="getCardValueList">
        <div v-if="!propJson.editFlag">
            <el-row :gutter="propJson.gutterSize" :style="rowStyle"
                    v-for="(item, itemIndex) in elRows" :key="item.id">
                <el-col :span="propJson.cardSpan" v-for="(colItem, colLength) in item" :key="item.id" @click="cardClick(colLength, elRows, itemIndex)">
                    <el-card style="width: 100%;" :shadow="propJson.shadowType">
                        <div class="itemClass" v-for="itemColInfo in propJson.list" >
                            <component :is="itemColInfo.component" :propJson="itemColInfo.propJson" :commonParam="cardSonCommonParam(colLength, elRows, itemIndex)">
                                <template v-slot:[itemSlot.slotName]="slotProps" v-for="itemSlot in slotList">
                                    <slot :name="itemSlot.slotName" :slotProps="slotProps"></slot>
                                </template>
                            </component>
                        </div>
                    </el-card>
                </el-col>
            </el-row>
        </div>

        <div v-if="propJson.editFlag" :info="getCardValueList">
            <el-card :style="execClass" :body-style="execBodyClass"
                     :shadow="propJson.shadowType">
                <div style="text-align: center;">
                    <span style="font-size: 13px; color: #606266">设计态只展示单个卡片，运行态渲染所有卡片</span>
                </div>
                <br/>
                <draggable v-if="propJson.editFlag"
                           :list="propJson.list"
                           animation="300"
                           :force-fallback="true"
                           :group="{name:'lowcode'}"
                           class="draggableClass"
                           item-key="id"
                >
                    <template #item="{ element }">
                        <div class="itemClass">
                            <component :is="element.component" :propJson="element.propJson" v-if="itemFlag" :commonParam="editCardSonCommonParam" @click.stop="" @dblclick.stop="changeComponentInfo(element)"/>
                            <component is="CloseCircleOutlined" class="closeClass" @click.stop="" @dblclick.stop="deleteComponent(element)"/>
                        </div>
                    </template>
                </draggable>
            </el-card>
        </div>
    </div>
</template>

<script name="CardListComponent" setup lang="ts">
import {deepCopy} from "@/utils/ywuCommon";
import {commonParamChange, getCommonParamObj} from "@/utils/commonParamUtil";
import {doThirdServiceAction, doThirdServiceValue} from "@/utils/lowcode/thirdService";
import jsonpath from "jsonpath";
import {computed, defineProps, ref} from "vue";
import {useLowCodeStore} from "@/stores/lowcode/lowcode";

let props = defineProps(['propJson', 'commonParam']);

let propJson = computed(() => {return props['propJson']})
let commonParam = computed(() => {return props['commonParam']})

let itemFlag = ref(true);
let cardListValue = ref([]);
let elRows = ref([]);

let execClass = computed(() => {
    let style = "";
    style += "width: 99.9%;"
    if (propJson.value.cardHeightType === "CUSTOM") {
        style += "height: " + propJson.value.cardHeight + ";";
    }
    return style;
})

let execBodyClass = computed(() => {
    let style = "";
    style += "padding: 0;";
    if (propJson.value.cardPaddingTop !== '') {
        style += "padding-top: " + propJson.value.cardPaddingTop + ";";
    }
    if (propJson.value.cardPaddingBottom !== '') {
        style += "padding-bottom: " + propJson.value.cardPaddingBottom + ";";
    }
    if (propJson.value.cardPaddingLeft !== '') {
        style += "padding-left: " + propJson.value.cardPaddingLeft + ";";
    }
    if (propJson.value.cardPaddingRight !== '') {
        style += "padding-right: " + propJson.value.cardPaddingRight + ";";
    }
    if (propJson.value.cardBodyWidth !== '') {
        style += "width: " + propJson.value.cardBodyWidth + ";";
    }
    return style
})

let getCardValueList = computed(async () => {
    if (propJson.value.editFlag) {
        return;
    }
    await doThirdServiceValue(propJson.value.cardListValueParam, commonParam.value, execCardValueListThen, execCardValueListCatch, {})
    await doElRows()
})

let rowStyle = computed(() => {
    let style = "";
    style += "margin-bottom:" + propJson.value.rowHeight + "px;";
    return style
})

let slotList = computed(() => {
    let res = getCommonParamObj(commonParam.value, "templateSlotInfo")
    return res.variableValue;
})

let editCardSonCommonParam = computed(() => {
    let cardSonCommonParam = deepCopy(commonParam.value)
    // 编辑泰下没个字段都赋值第一个数据
    for (let i = 0; i < propJson.value.paramVariableList.length; i++) {
        let variableList = propJson.value.paramVariableList[i]
        let commonParamObj = getCommonParamObj(cardSonCommonParam, variableList.globalVariableName)
        let value = commonParamObj.variableValue
        commonParamObj.variableType = "String"
        commonParamObj.variableValue = value[0]
    }
    return cardSonCommonParam;
})

function changeComponentInfo(element) {
    let lowCodeStore = useLowCodeStore();
    lowCodeStore.resetCurrentDrawer(element.drawerComponent)
    lowCodeStore.resetCurrentDrawerElementId(element.id);
    lowCodeStore.resetCurrentDrawerTitle(element.title)
    let copyJson = deepCopy(element.propJson)
    lowCodeStore.resetLowCodeDrawerJsonInfo(copyJson);
    lowCodeStore.resetIsShowDrawer(true)
    lowCodeStore.resetLowCodeComponentList(propJson.value.list)
}

function deleteComponent(element) {
    let colList = propJson.value.list
    // 获取当前列的LIST
    let index = -1;
    // 遍历当前列表，删除元素ID对应的数据
    for (let i = 0; i < colList.length; i++) {
        if (colList[i].id === element.id) {
            index = i;
        }
    }
    if (index >= 0) {
        propJson.value.list.splice(index, 1);
    }
}

function execCardValueListThen(resValue, execParam) {
    // 解析参数
    for (let i = 0; i < propJson.value.paramVariableList.length; i++) {
        let variableList = propJson.value.paramVariableList[i]
        // 从返回的结果中解析值
        let jsonPath = variableList.globalVariableParamName
        let commonParamObj = getCommonParamObj(commonParam.value, variableList.globalVariableName)
        let result = []
        if (commonParamObj.variableType === "Array") {
            if (Array.isArray(resValue) && resValue.length > 0) {
                result = jsonpath.query(resValue, jsonPath)
            } else {
                result = []
            }
        } else {
            result = jsonpath.query(resValue, jsonPath)[0]
        }
        commonParamObj.variableValue = result
        cardListValue.value = result
    }
}

function execCardValueListCatch(resValue) {

}

function cardSonCommonParam(colLength, elRows, itemIndex) {
    let index = itemIndex * elRows[0].length + colLength;
    let cardSonCommonParam = deepCopy(commonParam.value)
    // 编辑泰下没个字段都赋值第一个数据
    for (let i = 0; i < propJson.value.paramVariableList.length; i++) {
        let variableList = propJson.value.paramVariableList[i]
        let commonParamObj = getCommonParamObj(cardSonCommonParam, variableList.globalVariableName)
        let value = commonParamObj.variableValue
        commonParamObj.variableType = "String"
        commonParamObj.variableValue = value[index]
    }
    return cardSonCommonParam;
}

function cardClickExecThen(resValue) {
    // 将原始的变量（非卡片列表参数映射的变量重新回填到commonParam中），此处在于点击卡片之后可能会修改其他变量，导致关联关系中断
    for (let index = 0; index < commonParam.value.length; index++) {
        let commonInfo = commonParam.value[index]
        let flag = false
        for (let i = 0; i < propJson.value.paramVariableList.length; i++) {
            let variableList = propJson.value.paramVariableList[i]
            if (variableList.globalVariableName === commonInfo.variableName) {
                flag = true
                break;
            }
        }
        if (!flag) {
            // 获取返回后的值
            let commonParamObj = getCommonParamObj(resValue, commonInfo.variableName)
            // 重置参数
            commonParamChange(commonParam.value, commonInfo.variableName, commonParamObj.variableValue)
        }
    }
}

async function cardClick(colLength, elRows, itemIndex) {
    let index = itemIndex * elRows[0].length + colLength;
    let cardSonCommonParam = deepCopy(commonParam.value)
    // 编辑泰下没个字段都赋值第一个数据
    for (let i = 0; i < propJson.value.paramVariableList.length; i++) {
        let variableList = propJson.value.paramVariableList[i]
        let commonParamObj = getCommonParamObj(cardSonCommonParam, variableList.globalVariableName)
        let value = commonParamObj.variableValue
        commonParamObj.variableType = "String"
        commonParamObj.variableValue = value[index]
    }
    // 定义一个标志位，后续同步执行
    let awaitObj = {flag: false, res: true}
    await doThirdServiceAction(propJson.value.cardClickAction, awaitObj, cardSonCommonParam, cardClickExecThen, () => {}, cardSonCommonParam);
}

async function doElRows() {
    let newElRows = []
    let infoList = cardListValue.value;
    if (propJson.value.editFlag && !infoList) {
        newElRows = [[1]]
        return newElRows
    }
    // 根据当前卡片的宽度判断要分为几行展示
    let colNum = Math.floor(24 / propJson.value.cardSpan);
    let colInfo = []
    let colIndex = 0;
    for (let i = 0; i < infoList.length; i++) {
        if (colIndex >= colNum) {
            colIndex = 0;
            newElRows.push(colInfo)
            colInfo = []
        }
        colInfo.push(infoList[i])
        colIndex++
    }
    if (colIndex > 0) {
        newElRows.push(colInfo)
    }
    elRows.value = newElRows
}
</script>

<style scoped lang="less">
.draggableContainer {
    width: 98%;
    height: 85vh;
    margin-left: 1%;
    padding-top: 0.2%;
    transition: box-shadow 0.3s ease;
    box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.5);
    //去除光标
    caret-color: transparent;
    overflow: auto;
    .draggableClass {
        width: 100%;
        height: 100%;
    }
    .itemClass {
        position: relative;
        transition: box-shadow 0.3s ease;
        margin-bottom: 0.3%;
        .closeClass {
            display: none;
        }
    }
    .itemClass:hover {
        cursor: pointer;
        box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.5);
        .closeClass {
            position: absolute;
            color: #e76565;
            top: 2px;
            right: 2px;
            display: block;
        }
    }
}

.draggableContainer:hover {
    cursor: pointer;
}

.cardClass {
    width: 100%;
    height: 10vh;
}
</style>